package actor

import (
	"fmt"
)


type Actor interface {
	Tell(msg interface{}, sender Actor)
	DoReceive(receiveFunc func(msg interface{}, sender Actor), receiver interface{})
	Name() string
	Context() *Context
	OnStart()
	Stop()
	doStop()
	OnStop()
	MailboxLen() int
}

type Message struct {
	message interface{}
	sender  Actor
}

type SimpleActor struct {
	name     string
	context  *Context
	receiver interface{}
}

func (this *SimpleActor) Name() string {
	return this.name
}

func (this *SimpleActor) Tell(msg interface{}, sender Actor) {
	if this.context.state == RUNNING {
		this.context.mailbox.In() <- &Message{msg, sender}
		this.context.resize()
	} else {
		//TODO death letter
		fmt.Println("Death Letter ->  ", msg)
	}
}

func (this *SimpleActor) DoReceive(receiveFunc func(msg interface{}, sender Actor), receiver interface{}) {
	this.receiver = receiver
	this.context.start(receiveFunc, this)
	receiver.(Actor).OnStart()
}

func (this *SimpleActor) ActorOf(name string) SimpleActor {
	return this.context.actorOf(name, this)
}

func (this *SimpleActor) Self() *SimpleActor {
	return this
}

func (this *SimpleActor) System() *ActorSystem {
	return this.context.system
}

func (this *SimpleActor) Context() *Context {
	return this.context
}

func (this *SimpleActor) Child(name string) Actor {
	return this.context.getActorByName(name)
}

func (this *SimpleActor) OnStart() {
	fmt.Println(this.name + " OnStart")
}

func (this *SimpleActor) doStop() {
	this.receiver.(Actor).OnStop()
}

func (this *SimpleActor) Stop() {
	this.Tell(PoisonPill, this.Self())
}

func (this *SimpleActor) OnStop() {
	fmt.Println(this.name + " OnStart")
}

func (this *SimpleActor) MailboxLen() int {
	return this.context.mailbox.Len()
}

func (this *SimpleActor) MailBoxCap() int {
	return int(this.context.mailbox.Cap())
}








